package com.ucar.widget;

import com.ucar.R;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.AbsListView.OnScrollListener;

/**
 * 下拉上拉更新刷新的自定义ListView
 * @author Administrator
 *
 */
public class PullToRefreshView extends ListView implements OnScrollListener {
	private static final String TAG = "PullToRefreshView"; 
	// 变为向下的箭头,改变箭头方向
	private RotateAnimation mFlipAnimation;
	// 变为逆向的箭头,旋转
	private RotateAnimation mReverseFlipAnimation;
	
	// layout inflater
	private LayoutInflater mInflater;
	
	// 头部底部View
	private View mHeaderView;
	private View mFooterView;
	
	// 头部刷新中的子view
	private ImageView mHeaderImageView;
	private TextView mHeaderTextView;
	private TextView mHeaderUpdateTextView;
	private ProgressBar mHeaderProgressBar;
	//底部刷新view的高度
	private int mHeaderViewHeight;
	
	// 底部刷新中的子view
	private ImageView mFooterImageView;
	private TextView mFooterTextView;
	private ProgressBar mFooterProgressBar;
	//底部刷新view的高度
	private int mFooterViewHeight;
	
	// 拉动状态
	private int mPullState = PULL_DONE_STATE;
	// 拉动状态：上拉，下拉
	private static final int PULL_DONE_STATE = -1;
	private static final int PULL_UP_STATE = 0;
	private static final int PULL_DOWN_STATE = 1;
	
	// 头部刷新的状态
	private int mHeaderState;
	// 底部刷新的状态
	private int mFooterState;
	
	// 刷新状态
	private static final int PULL_TO_REFRESH = 2;
	private static final int RELEASE_TO_REFRESH = 3;
	private static final int REFRESHING = 4;
	private static final int DONE = 5;
	
	// 刷新接口
	private OnRefreshListener mOnRefreshListener;
	
	/**
	 * 上一次触摸的纵轴Y的位置
	 */
	private int mLastMotionY;
	

	public PullToRefreshView(Context context) {
		super(context);
		init(context);
	}
	
	public PullToRefreshView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context);
	}
	
	/**
	 * 初始化函数
	 * @param context
	 */
	private void init(Context context) {
		// 初始化动画
		mFlipAnimation = new RotateAnimation(0, -180,
				RotateAnimation.RELATIVE_TO_SELF, 0.5f,
				RotateAnimation.RELATIVE_TO_SELF, 0.5f);
		mFlipAnimation.setInterpolator(new LinearInterpolator());
		mFlipAnimation.setDuration(250);
		mFlipAnimation.setFillAfter(true);
		mReverseFlipAnimation = new RotateAnimation(-180, 0,
				RotateAnimation.RELATIVE_TO_SELF, 0.5f,
				RotateAnimation.RELATIVE_TO_SELF, 0.5f);
		mReverseFlipAnimation.setInterpolator(new LinearInterpolator());
		mReverseFlipAnimation.setDuration(250);
		mReverseFlipAnimation.setFillAfter(true);
		
		mInflater = LayoutInflater.from(context);		
		
		// 添加头部刷新View
		addRefreshHeaderView();
		
		// 添加低部刷新View
		addRefreshFooterView();
	}

	/**
	 * 添加头部刷新View
	 */
	private void addRefreshHeaderView()
	{
		mHeaderView = mInflater.inflate(R.layout.refresh_header, this, false);
		mHeaderImageView = (ImageView) mHeaderView
				.findViewById(R.id.pull_to_refresh_image);
		mHeaderTextView = (TextView) mHeaderView
				.findViewById(R.id.pull_to_refresh_text);
		mHeaderUpdateTextView = (TextView) mHeaderView
				.findViewById(R.id.pull_to_refresh_updated_at);
		mHeaderProgressBar = (ProgressBar) mHeaderView
				.findViewById(R.id.pull_to_refresh_progress);
		
		// 测量头部刷新View的大小
		measureView(mHeaderView);
		mHeaderViewHeight = mHeaderView.getMeasuredHeight();
		Log.e(TAG, "mHeaderViewHeight-" + mHeaderViewHeight);
		mHeaderView.setPadding(0, -mHeaderViewHeight, 0, 0);
		mHeaderView.invalidate();
		addHeaderView(mHeaderView, null, false);
	}
	
	/**
	 * 添加低部刷新View
	 */
	private void addRefreshFooterView()
	{
		mFooterView = mInflater.inflate(R.layout.refresh_footer, this, false);
		mFooterImageView = (ImageView) mFooterView
				.findViewById(R.id.pull_to_load_image);
		mFooterTextView = (TextView) mFooterView
				.findViewById(R.id.pull_to_load_text);
		mFooterProgressBar = (ProgressBar) mFooterView
				.findViewById(R.id.pull_to_load_progress);
		
		// 测量低部刷新View的大小
		measureView(mFooterView);
		mFooterViewHeight = mFooterView.getMeasuredHeight();
		Log.e(TAG, "mFooterViewHeight-" + mFooterViewHeight);
		mFooterView.setPadding(0, 0, 0, -mFooterViewHeight);
		mFooterView.invalidate();
		addFooterView(mFooterView, null, false);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
			case MotionEvent.ACTION_DOWN:
				// 获得当前纵坐标的位置
				int y = (int) event.getY();
				mLastMotionY = y;
				break;
			case MotionEvent.ACTION_MOVE:
				// 获得当前纵坐标的位置
				y = (int) event.getY();
				// 获得移动的距离
				int deltaY = y - mLastMotionY;
				Log.e(TAG, "mLastMotionY-" + mLastMotionY);
				Log.e(TAG, "deltaY-" + deltaY);
				
				// 如果可见的item位置是ListView的第一个item，就进行下拉刷新操作
				if(this.getFirstVisiblePosition() == 0 && mHeaderState != REFRESHING && mPullState != PULL_UP_STATE)
				{
					if(deltaY > 0)
					{
						// 设置下拉状态
						mPullState = PULL_DOWN_STATE;
						// 每次设置显示到第一个item
						this.setSelection(0);
						// 然后进行mHeaderView顶部padding的设置
						mHeaderView.setPadding(0, deltaY / 3 - mHeaderViewHeight, 0, 0);
						// 如果拉动的距离大于等于mHeaderViewHeight的1.5且之前是下拉状态进行状态的改变为松开状态
						if((deltaY / 3) >= (1.5 * mHeaderViewHeight) && mHeaderState != RELEASE_TO_REFRESH)
						{
							mHeaderState = RELEASE_TO_REFRESH;
							changeHeaderViewByState(false);
						}
						// 如果拉动的距离小于mHeaderViewHeight的1.5，就讲状态改为下拉状态
						else if((deltaY / 3) < (1.5 * mHeaderViewHeight))
						{
							// 如果之前是松开状态，就进行图标改变动画
							if(mHeaderState == RELEASE_TO_REFRESH)
							{
								mHeaderState = PULL_TO_REFRESH;
								changeHeaderViewByState(true);
							}
							// 否则不执行动画改变
							else
							{
								mHeaderState = PULL_TO_REFRESH;
								changeHeaderViewByState(false);
							}
						}
					}
				}
				// 如果可见的item位置是ListView的最后一个item，就进行上拉刷新操作
				if(this.getLastVisiblePosition() == this.getCount() - 1 && mFooterState != REFRESHING && mPullState != PULL_DOWN_STATE)
				{
					if (deltaY < 0) {
						// 设置下拉状态
						mPullState = PULL_UP_STATE;
						// 每次设置显示到最后一个item
						this.setSelection(this.getCount() - 1);
						// 然后进行mFooterView顶部padding的设置
						mFooterView.setPadding(0, 0, 0, -deltaY / 3 - mFooterViewHeight);
						// 如果拉动的距离大于等于mHeaderViewHeight的1.5且之前是下拉状态进行状态的改变为松开状态
						if ((-deltaY / 3) >= (1.5 * mFooterViewHeight) && mFooterState != RELEASE_TO_REFRESH) 
						{
							mFooterState = RELEASE_TO_REFRESH;
							changeFooterViewByState(false);
						} 
						// 如果拉动的距离小于mHeaderViewHeight的1.5，就讲状态改为下拉状态
						else if ((-deltaY / 3) < (1.5 * mFooterViewHeight)) 
						{
							// 如果之前是松开状态，就进行图标改变动画
							if(mFooterState == RELEASE_TO_REFRESH)
							{
								mFooterState = PULL_TO_REFRESH;
								changeFooterViewByState(true);
							}
							// 否则不执行动画改变
							else
							{
								mFooterState = PULL_TO_REFRESH;
								changeFooterViewByState(false);
							}
						}
					} 
				}
				break;
			case MotionEvent.ACTION_UP:
				// 如果是下拉更新
				if(mPullState == PULL_DOWN_STATE)
				{
					// 如果是松开状态，就进行更新状态的改变，更新相应的数据
					if(mHeaderState == RELEASE_TO_REFRESH)
					{
						mHeaderState = REFRESHING;
						changeHeaderViewByState(false);
					}
					// 如果不是处于更新状态，就恢复原样
					else if(mHeaderState != REFRESHING)
					{
						mHeaderState = DONE;
						changeHeaderViewByState(false);
					}
				}
				// 如果是上拉加载
				else if(mPullState == PULL_UP_STATE)
				{
					// 如果是松开状态，就进行更新状态的改变，更新相应的数据
					if(mFooterState == RELEASE_TO_REFRESH)
					{
						mFooterState = REFRESHING;
						changeFooterViewByState(false);
					}
					// 如果不是处于更新状态，就恢复原样
					else if(mFooterState != REFRESHING)
					{
						mFooterState = DONE;
						changeFooterViewByState(false);
					}
				}
				break;
		}
		return super.onTouchEvent(event);
	}
	
	/**
	 * 根据状态改变头部刷新的显示内容
	 * @param isBack 是否为松开变成下拉状态
	 */
	private void changeHeaderViewByState(boolean isBack)
	{
		switch (mHeaderState) {
			// 如果是下拉状态
			case PULL_TO_REFRESH:
				// 松开变成下拉状态,进行图标的改变动画
				if(isBack)
				{
					mHeaderImageView.clearAnimation();
					mHeaderImageView.startAnimation(mReverseFlipAnimation);
				}
				mHeaderTextView.setText(R.string.pull_to_refresh_text);
				break;
			// 如果是松开状态
			case RELEASE_TO_REFRESH:
				// 进行图标的改变动画
				mHeaderImageView.clearAnimation();
				mHeaderImageView.startAnimation(mFlipAnimation);
				mHeaderTextView.setText(R.string.release_to_refresh_text);
				break;
			// 如果是刷新状态
			case REFRESHING:
				mHeaderImageView.clearAnimation();
				mHeaderView.setPadding(0, mHeaderViewHeight / 4, 0, mHeaderViewHeight / 4);
				mHeaderProgressBar.setVisibility(View.VISIBLE);
				mHeaderImageView.setVisibility(View.GONE);
				mHeaderTextView.setText(R.string.refresh_load);
				mHeaderUpdateTextView.setVisibility(View.GONE);
				
				// 进行数据刷新
				mOnRefreshListener.onHeaderRefresh();
				break;
			// 如果是完成状态
			case DONE:
				mPullState = PULL_DONE_STATE;
				mHeaderProgressBar.setVisibility(View.GONE);
				mHeaderImageView.setVisibility(View.VISIBLE);
				mHeaderUpdateTextView.setVisibility(View.VISIBLE);
				mHeaderView.setPadding(0, -mHeaderViewHeight, 0, 0);
				this.setSelection(0);
				break;
			
		}
	}
	
	/**
	 * 根据状态改变低部刷新的显示内容
	 * @param isBack 是否为松开变成下拉状态
	 */
	private void changeFooterViewByState(boolean isBack)
	{
		switch (mFooterState) {
			// 如果是下拉状态
			case PULL_TO_REFRESH:
				// 松开变成下拉状态,进行图标的改变动画
				if(isBack)
				{
					mFooterImageView.clearAnimation();
					mFooterImageView.startAnimation(mReverseFlipAnimation);
				}
				mFooterTextView.setText(R.string.pull_to_load_text);
				break;
			// 如果是松开状态
			case RELEASE_TO_REFRESH:
				// 进行图标的改变动画
				mFooterImageView.clearAnimation();
				mFooterImageView.startAnimation(mFlipAnimation);
				mFooterTextView.setText(R.string.release_to_load_text);
				break;
			// 如果是刷新状态
			case REFRESHING:
				mFooterImageView.clearAnimation();
				mFooterView.setPadding(0, mFooterViewHeight / 4, 0, mFooterViewHeight / 4);
				mFooterProgressBar.setVisibility(View.VISIBLE);
				mFooterImageView.setVisibility(View.GONE);
				mFooterTextView.setText(R.string.refresh_load);
				
				// 进行数据刷新
				mOnRefreshListener.onFooterRefresh();
				break;
			// 如果是完成状态
			case DONE:
				mPullState = PULL_DONE_STATE;
				mFooterProgressBar.setVisibility(View.GONE);
				mFooterImageView.setVisibility(View.VISIBLE);
				mFooterView.setPadding(0, 0, 0, -mFooterViewHeight);
				//this.setSelection(this.getCount() - 1);
				break;
		}
	}
	
	/**
	 * 完成头部刷新
	 */
	public void onHeaderRefreshCompleted()
	{
		mHeaderState = DONE;
		changeHeaderViewByState(false);
	}
	
	/**
	 * 完成底部刷新
	 */
	public void onFooterRefreshCompleted()
	{
		mFooterState = DONE;
		changeFooterViewByState(false);
	}
	
	/**
	 * 设置刷新实现类
	 * @param headerRefreshListener
	 */
	public void setOnRefreshListener(
			OnRefreshListener refreshListener) {
		mOnRefreshListener = refreshListener;
	}

	/**
	 * 刷新回调接口
	 * @author 7Sing
	 *
	 */
	public interface OnRefreshListener {
		public void onHeaderRefresh();
		
		public void onFooterRefresh();
		
		public void onIsLoadImage(boolean isLoadImage);
	}

	/**
	 * 测量View大小方法
	 * @param child
	 */
	private void measureView(View child) {
		ViewGroup.LayoutParams p = child.getLayoutParams();
		if (p == null) {
			p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
					ViewGroup.LayoutParams.WRAP_CONTENT);
		}

		int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);
		int lpHeight = p.height;
		int childHeightSpec;
		if (lpHeight > 0) {
			childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,
					MeasureSpec.EXACTLY);
		} else {
			childHeightSpec = MeasureSpec.makeMeasureSpec(0,
					MeasureSpec.UNSPECIFIED);
		}
		child.measure(childWidthSpec, childHeightSpec);
	}

	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) {
		if(mOnRefreshListener != null)
		{
			if (scrollState == OnScrollListener.SCROLL_STATE_TOUCH_SCROLL || scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
				mOnRefreshListener.onIsLoadImage(true);
			}
			else
			{
				mOnRefreshListener.onIsLoadImage(false);
			}
		}
	}

	@Override
	public void onScroll(AbsListView view, int firstVisibleItem,
			int visibleItemCount, int totalItemCount) {
	}
}
